
#include "Shared_ptr.h"



template<class T>
class Del
{
public:
	void operator()(const T* ptr)
	{
		delete[] ptr;
	}
};


unique_ptr<Date> test_retvalue()
{
	unique_ptr<Date> sp(new Date);
	// 因为 unique_ptr 不支持赋值和拷贝，所以不能传值返回
	return sp;
}

// unique_ptr shared_ptr 的使用方法
int main1()
{
	// unique_ptr 不支持拷贝和赋值
	unique_ptr<Date> up(new Date);
	// 析构多个空间的时候需要自己传析构函数的模板
	unique_ptr<Date, Del<Date>> up1(new Date[5]);
	unique_ptr<Date[]> up2(new Date[5]);           // 特化版本

	// shared_ptr 支持拷贝和赋值 指向的同一块空间，底层使用计数析构来解决问题
	shared_ptr<Date> sp(new Date);

	shared_ptr<Date> sp1(sp);
	shared_ptr<Date> sp2 = sp1;
	// shared_ptr 在析构多个空间的时候仍然需要自己传析构函数，不过是在构造函数的地方传
	shared_ptr<Date> sp3(new Date[5], Del<Date>());
	shared_ptr<Date[]> sp4(new Date[5]);        //特化版本

	// 由于编译器做了优化，将亡值按理来说会转化为右值直接移动构造过来，但是我的编译器做了更高的优化
	// up2 和函数的返回值是一个智能指针，所以不会报错
	unique_ptr<Date> up3 = test_retvalue();

	return 0;
}



// weak_ptr 解决循环引用的问题
//struct ListNode
//{
//	int _data;
//	Shared_ptr<ListNode> _next;
//	Shared_ptr<ListNode> _prev;
//	ListNode()
//		:_data(0)
//		,_next(nullptr)
//		,_prev(nullptr)
//	{}
//	~ListNode()
//	{
//		cout << "~ListNode()" << endl;
//	}
//};

int main2()
{
	//Shared_ptr<ListNode> Sp1(new ListNode);
	//Shared_ptr<ListNode> Sp2(new ListNode);

	//Sp1->_next = Sp2;
	//Sp2->_prev = Sp1;

	// 循环引用(内存泄露)
	// 当出现循环引用的时候就会出现内存泄露，上面就是循环引用的操作
	// 主函数结束，Sp2 先析构，Sp2里面的析构因子减减，因为循环引用，Sp1 中的next还引用着Sp2 所以Sp2 也不会被析构
	// 析构 Sp1 的时候因为 Sp2 中的prev 指针还引用着 Sp1 所以Sp1不会被析构

	return 0;
}

int main3()
{
	//function<void(Date*)> _del = [](Date* ptr) { delete ptr; };        // 析构一个空间
	function<void(Date*)> del = [](Date* ptr) { delete[] ptr; };
	Shared_ptr<Date> Sp(new Date[5],del);
	Shared_ptr<Date> Sp1(Sp);
	Shared_ptr<Date> Sp2(new Date);
	Sp2 = Sp1;
	Sp->_year++;
	//cout << Sp->_year << " " << Sp->_month << " " << Sp->_day << endl;



	return 0;
}


struct ListNode
{
	int _data;
	Weak_ptr<ListNode> _next;
	Weak_ptr<ListNode> _prev;
	ListNode()
		:_data(0)
	{}
	~ListNode()
	{
		cout << "~ListNode()" << endl;
	}
};

// 解决循环引用的内存泄露问题 
// weak_ptr 解决内存泄露问题
int main()
{

	Shared_ptr<ListNode> Sp1(new ListNode);
	Shared_ptr<ListNode> Sp2(new ListNode);

	Sp1->_next = Sp2;
	Sp2->_prev = Sp1;

	return 0;;
}